home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / movbasic.arc / MOVBASIC.ASM next >
Assembly Source File  |  1986-10-07  |  19KB  |  520 lines

  1. Title    MOVBASIC    3-3-86    [9-17-86]
  2. Page    80,132
  3. ;This program must be run on an IBM-PC or IBM-PC/at with ROMS installed
  4. ;BASIC.COM and BASICA.COM must reside in same directory as MOVBASIC.
  5. ;
  6. ;The program takes IBM basic.com or basica.com and combines it with the
  7. ;rom image to create a new file called SBASIC.COM or SBASICA.COM, and
  8. ;it now works with files above 32k such as PC-DOS 3.2 file BASICA.COM
  9. ;
  10. ;These new programs can be run on clones with out the copyrighted IBM
  11. ;basic ROMS, and will act as if they were running on a true IBM-PC
  12. ;
  13. ;Works great, type MOVBASIC and follow the prompts...
  14. ;
  15. ;To generate the executable MOVBASIC.COM file, please type
  16. ;
  17. ;    MASM MOVBASIC;
  18. ;    LINK MOVBASIC;
  19. ;    EXE2BIN MOVBASIC MOVBASIC.COM;
  20. ;
  21. lf    equ    0Ah                ; Ascii carriage return
  22. cr    equ    0Dh                ; Ascii line     feed
  23. ;
  24. fcb    equ    5Ch                ; Address of FCB in PSP
  25. fixmax    equ    50h                ; Maximum number of fixups
  26. ;
  27. prog    segment
  28.     assume    cs:prog ,ds:prog, es:prog ,ss:prog
  29.     org    0100h
  30. ;
  31. main    proc    near                ;Main procedure
  32.     mov    sp,offset main            ; ..use   local stack
  33.     call    copy                ; ..read  ROM
  34.     call    rfile                ; ..read  BASICx.COM
  35.     call    fixup                ; ..scan  BASICx.COM for Fixups
  36.     call    sizit                ; ..find  size, save in HDR
  37.     call    chksum                ; ..save  chksum     in HDR
  38.     call    wfile                ; ..write Fixups+ROM+BASICx.COM
  39.     int    20h                ; ..all done, back to DOS
  40. main    endp                    ; ..end of main procedure
  41. ;
  42. subttl    copy - procedure to make copy of hardware 'ROM' basic
  43. copy    proc    near                ; Makes copy of ROM
  44.     xor    ax,ax                ; ...get bios data
  45.     mov    ds,ax                ; ...area in ds seg
  46.     mov    bx,60h                ; ...BX --> basic in 'ROM's
  47.     mov    ax,[bx+0]            ; Check ibm ROM vector offset
  48.     or    ax,ax                ; ...offset must be zero
  49.     jnz    badrom                ; ...else no IBM roms
  50.     mov    ax,[bx+2]            ; Check ibm ROM vector segment
  51.     cmp    ax,0F600h            ; ...must begin at F600
  52.     jnz    badrom                ; ...else no IBM roms
  53.     mov    ds,ax                ; AX --> IBM rom segment
  54.     mov    cx,8000h            ; CX ==  size of ROM basic
  55.     mov    di,offset ibmbas        ; DI --> Private 'ROM' offset
  56.     mov    si,0                ; SI --> IBM     'ROM' offset
  57.     cld                    ;  ...direction forwards
  58.     repz    movsb                ; Copy IBM rom into 'ROM' area
  59.     push    cs                ;  ...then restore
  60.     pop    ds                ;  ...data segment
  61.     ret                    ; All done, back to caller
  62. ;
  63. badrom:    push    cs                ; Restore the
  64.     pop    ds                ;  ...data segment
  65.     mov    dx,offset rommsg        ; DX --> error message
  66.     jmp    near ptr errxit            ;  ...print and expire
  67. copy    endp                    ; End of copy procedure
  68. ;
  69. rommsg    db    cr,lf
  70.     db    'Please run this program on an IBM computer with'
  71.     db    ' the basic ROMS installed',cr,lf,7,'$'
  72. ;
  73. subttl    rfile - procedure to read contents of original ibm BASICx.COM file
  74. rfile    proc    near                ; Procedure reads BASICx.COM
  75.     mov    al,byte ptr ds:fcb+01h        ; AL = First char of filename
  76.     cmp    al,20h    ;' '            ;  ...was filename specified
  77.     jz    menu                ;  ...no, then prompt for it
  78.     mov    al,byte ptr ds:fcb+10h        ; Was a disk number specified?
  79.     cmp    al,0Fh                ;  ...valid only up to 0Fh
  80.     jb    disk                ; Else force default disk
  81.     xor    al,al                ;  ...by zeroing disk number
  82. ;
  83. disk:    mov    ofile,al            ; Save disk number in FCB
  84.     jmp    short    try            ;  ...try to open file
  85. ;
  86. menu:    call    prompt                ; Print selection for user
  87. try:    mov    di,offset fcb+09h        ; DI --> extension in FCB
  88.     mov    ax,04F43h            ; AX ==  'CO'
  89.     cld                    ;  ...clear direction
  90.     stosw                    ;  ...save 'CO' in extension
  91.     mov    al,4Dh    ;'M'            ; AL ==  'M'
  92.     stosb                    ;  ...save 'M' in extension
  93.     mov    cx,1Eh                ; CX == byte count for reset
  94.     xor    al,al                ; AL == what to put in bytes
  95.     repz    stosb                ;  ...reset remainder of FCB
  96.     mov    ah,0Fh                ; AH == open existing file
  97.     mov    dx,offset fcb            ; DX --> fcb for this file
  98.     int    21h                ;  ...try to open the file
  99.     or    al,al                ;Test the return code from DOS
  100.     jz    opened                ;  ...all is ok
  101.     mov    dx,offset filmsg        ; Else DX --> nasty message
  102.     mov    ah,09h                ;  ... AX ==  DOS print request
  103.     int    21h                ;  ... let DOS complain
  104.     dec    byte ptr tries            ; One less retry (began with 2)
  105.     jnz    menu                ;  ... has second chance
  106.     int    20h                ; Else call the terminator
  107. ;
  108. opened: mov    word ptr ds:fcb+0Eh,01h        ; Records are 1h bytes long
  109.     push    ds                ; Save data segment
  110.     mov    ah,1Ah                ; AH == set disk xfer address
  111.     mov    bx,ds                ; Get current segment
  112.     add    bx,800h                ;  ...point beyond ROMs
  113.     mov    ds,bx                ; Load into DS segment
  114.     mov    dx,offset ibmbas        ;  ...xfer address = 'ROM'end
  115.     int    21h                ;  ...tell DOS to set address
  116.     pop    ds                ; Restore data segment
  117.     mov    ah,27h                ; Attempt to read entire file
  118.     mov    cx,offset 0FFFFh        ;  ...only up to 64k bytes
  119.     mov    dx,offset fcb            ;  ...with this FCB
  120.     int    21h                ;  ...into disk xfer address
  121.     cmp    al,01h                ; Must return end_of_file
  122.     jnz    huge                ;  ...else file is oversize
  123.     cmp    ds:ibmbas+8000h,5A4Dh        ; Is file a COM file?
  124.     je    exefil                ;  ...no, can't move it
  125.     mov    word ptr ds:ifsize,cx        ; Save size in 1h byte blocks
  126.     ret                    ;  ...all done read, return
  127. ;
  128. huge:    jmp    near ptr toobig            ;  ...else can't convert
  129. exefil:    jmp    near ptr notcom            ;  ...not a COM file
  130. rfile    endp                    ; End of read file procedure
  131. ;
  132. subttl    prompt - procedure to get filename from user
  133. prompt    proc    near                ; Prompt for BASICx file name
  134.     mov    dx,offset banner        ; DX --> display
  135.     mov    ah,09h                ; AH ==  print string
  136.     int    21h                ;  ...ask DOS to print prompt
  137.     mov    ah,01h                ; Read reply from console
  138.     int    21h                ;  ...this DOS request
  139.     sub    al,31h                ; Was it choice #1?
  140.     jz    newnam                ;  ...yup
  141.     cmp    al,01h                ; Was it choice #2?
  142.     jnz    prompt                ;  ...nope, must be 1 or 2
  143.     mov    byte ptr ifpat,41h    ;'A'    ; Add 'A' to end of filename
  144. ;
  145. newnam:    mov    si,offset ifile            ; Pack explicit name
  146.     mov    di,offset fcb            ;  ...into input FCB
  147.     mov    cx,0Ch                ;  ...length of name
  148.     cld                    ; Clear direction flag
  149.     repz    movsb                ; ...copy name there
  150.     mov    cx,18h                ; ...reset input FCB
  151.     xor    al,al                ; ...write zero to it
  152.     repz    stosb                ; ...with instruction
  153.     ret                    ; Back to caller
  154. prompt    endp                    ; ...end of procedure
  155. ;
  156. tries    db    2                ; Attempts before we give up
  157. ;
  158. banner    db    cr,lf,lf
  159.     db    '                  BASIC Relocation Utility Version 3.01'
  160.     db    cr,lf,lf,lf
  161.     db    'This program will convert BASIC.COM or BASICA.COM into'    
  162.     db    ' SBASIC[A].COM which is',cr,lf    
  163.     db    'usable on CLONE COMPUTERs that do not have IBM`s patented '    
  164.     db    'BASIC ROMs installed',cr,lf,lf
  165.     db    'If you have BASIC[A].COM on non-default drive',2Ch
  166.     db    'then specify that in the command ',cr,lf
  167.     db    'line. For ex. MOVBASIC A:BASIC B: will create SBASIC.'    
  168.     db    'COM on the B: drive. ',cr,lf,lf
  169.     db    'Select BASIC to patch for CLONE (non-IBM) computer'
  170.     db    cr,lf,lf
  171.     db    '              1. BASIC.COM   -->  SBASIC.COM',cr,lf    
  172.     db    '              2. BASICA.COM  -->  SBASICA.COM',cr,lf
  173.     db    '        -->   $'
  174. ;
  175. filmsg    db    cr,lf,'Cannot find specified file.  Please retry.',7,'$'    
  176. ;
  177. ifile    db    0                ; Disk number
  178.     db    'BASIC'                ;  ...filename
  179. ifpat    db    '   '                ;  ...possibly 'A'
  180.     db    'COM'                ;  ...extension
  181. ;
  182. subttl    fixup - procedure to build table of fixup offsets
  183. fixup    proc    near                ; Revector ROM references
  184.     mov    bx,offset ibmbas        ; BX => BASICx.COM in memory
  185.     mov    cx,word ptr ds:ifsize        ; CX == Size in 1h byte blocks
  186.     mov    dx,0F600h            ; DX == hardware (ROM) address
  187.     push    ds                ; Save data segment
  188.     mov    ax,ds                ; Get data segment
  189.     add    ax,800h                ;  ...move beyond ROMs
  190.     mov    ds,ax                ; Load into data  segment
  191.     mov    di,offset fixups        ; DI -> start of fixup table
  192.     cld                    ; ...clear direction flag
  193. ;
  194. fixing:    cmp    dx,[bx]                ; BASICx.COM want ROM segment?
  195.     jnz    next                ;  ...no, do not alter
  196.     call    lookup                ; Should seg. ref. be fixed up?
  197.     jnz    next                ;  ...flag 'Z' clear if no
  198.     mov    ax,bx                ; Get address that needs fixup
  199.     sub    ax,offset ibmbas        ;  ...find BASICx.COM offset
  200.     stosw                    ; Store offset in fixups table
  201.     inc    word ptr cs:nfixes        ;  ...one more offset in table
  202. next:    inc    bx                ; Scan the next byte
  203.     loop    fixing                ;  ...until done BASICx.COM
  204.     pop    ds                ; Restore Data segment
  205.     cmp    word ptr ds:nfixes,fixmax    ; Did fixup table overflow?
  206.     ja    loaded                ;  ...jump if so
  207.     ret                    ; Else end of fixup procedure
  208. ;
  209. loaded:    jmp    near ptr tooful            ; Fixup table overloaded
  210. ;
  211. fixup    endp                    ;  ...show end
  212. subttl    lookup - find if offset into BASICx.COM needs fixup
  213. ;
  214. ; Lookup - procedure sets 'Z' flag if this F600h reference needs a fixup
  215. ;
  216. lookup    proc    near                ; See if reference needs fixup
  217.     cmp    byte ptr [bx-3],0EAh
  218.     jz    found
  219.     cmp    byte ptr [bx-1],0B8h
  220.     jz    found
  221.     cmp    byte ptr [bx-1],0BBh
  222.     jz    found
  223.     cmp    byte ptr [bx-1],0BEh
  224.     jz    found
  225.     cmp    byte ptr [bx-1],0BAh
  226.     jz    found
  227.     cmp    byte ptr [bx-1],0BFh
  228.     jz    found
  229.     cmp    byte ptr [bx-1],0B9h
  230.     jz    found
  231.     cmp    byte ptr [bx-3],09Ah
  232.     jz    found
  233.     cmp    word ptr [bx-4],06C7h
  234.     jz    found
  235.     cmp    word ptr [bx-4],87C7h
  236.     jz    found
  237.     cmp    word ptr [bx-4],84C7h
  238.     jz    found
  239.     cmp    word ptr [bx-4],85C7h
  240.     jz    found
  241.     cmp    word ptr [bx-4],86C7h
  242.     jz    found
  243.     cmp    word ptr [bx-3],46C7h
  244.     jz    found
  245.     cmp    word ptr [bx-3],47C7h
  246.     jz    found
  247.     cmp    word ptr [bx-3],44C7h
  248.     jz    found
  249.     cmp    word ptr [bx-3],45C7h
  250.     jz    found
  251.     cmp    word ptr [bx-2],07C7h
  252.     jz    found
  253.     cmp    word ptr [bx-2],04C7h
  254.     jz    found
  255.     cmp    word ptr [bx-2],05C7h
  256. found:    ret                    ; Return, result in Z flag
  257. lookup    endp                    ;  ...end of procedure
  258. ;
  259. subttl    sizit - procedure to find size of SBASIC.COM and save in HDR
  260. sizit    proc    near
  261.     mov    ax,offset ibmbas-hdr        ; Get header size into AX
  262.     add    ax,8000h            ;  ...add size of ROM set
  263.     add    ax,word ptr ifsize        ;  ...and input file size
  264.     push    ax                ; Save copy of file size
  265.     mov    cl,09h                ;  ...find number of blocks
  266.     rcr    ax,cl                ;  ...by 9 bit right shift
  267.     and    ax,0FFh                ;  ...0FFh blocks maximum
  268.     inc    ax                ; I dunno, but DOS wants it
  269.     mov    word ptr hdr+04h,ax        ; Save number of blocks in hdr
  270.     pop    ax                ;  ...get low order 16 bits
  271.     and    ax,01FFh            ; Isolate the block fraction
  272.     mov    word ptr hdr+02h,ax        ;  ...and save in hdr word
  273.     ret                    ;  ...return to caller
  274. sizit    endp
  275. ;
  276. subttl    chksum - procedure to calculate and store negative checksum of file
  277. chksum    proc    near
  278.     xor    ax,ax                ; Prepare a zero
  279.     mov    dx,word ptr hdr+04h        ; Load block count
  280. chks01:    mov    si,offset movrom        ; si --> blk start
  281.     dec    dx                ;  ...show one less
  282.     js    chks03                ; Negative if done
  283.     mov    cx,0100h            ;  ...words in block
  284. chks02:    sub    ax,[si]                ; Subtract word
  285.     add    si,02h                ;  ...point to next
  286.     loop    chks02                ;  ...go until done
  287.     mov    bx,ds                ;  ...get a copy
  288.     add    bx,0020h            ;  ...Go to next blk
  289.     mov    ds,bx                ;  ...and save in ds
  290.     jmp    chks01                ;  ...back for next
  291. chks03:    mov    cx,offset hdr+02h        ; Get fraction blk
  292.     shr    cx,01h                ;  ...into words
  293.     jcxz    chks05                ; Zero if all done
  294. chks04:    sub    ax,[si]                ; Subtract word
  295.     add    si,02h                ;  ...point to next
  296.     loop    chks04                ;  ...go until done
  297. chks05:    push    cs                ; Get code segment
  298.     pop    ds                ;  ...restore ds
  299.     mov    word ptr hdr+12h,ax        ; Negative chksum
  300.     ret                    ;  ...return caller
  301. chksum    endp
  302. ;
  303. subttl    wfile - procedure to write new SBASICx.COM file
  304. wfile    proc    near                ; Procedure writes BASICx.COM
  305.     mov    al,byte ptr ds:fcb+06h        ; Last character of filename
  306.     cmp    al,41h                ;  ...does it end in 'A'?
  307.     jnz    around                ;  ...no, leave it alone
  308.     mov    ofpat,al            ;  ...else copy 'A'
  309. around:    mov    ah,16h                ; Create output file
  310.     mov    dx,offset ofile            ;  ...with (patched) FCB
  311.     int    21h                ;  ...with system call
  312.     or    al,al                ; Did the create work?
  313.     jnz    dskcre                ;  ...say disk is full
  314.     mov    word ptr orecl,01h        ; Records are 1 byte long
  315.     mov    cx,offset ibmbas-hdr        ;  ...overhead in bytes
  316.     add    cx,8000h            ;  ...rom size in bytes
  317.     jc    toobig                ; Out of memory, complain(?!)
  318.     mov    ah,1Ah                ; Set disk transfer address
  319.     mov    dx,offset hdr            ;  ...to our start-up code
  320.     int    21h                ;  ...with this call
  321.     mov    dx,offset ofile            ; DX --> Output FCB
  322.     mov    ah,28h                ;  ...write patched file
  323.     int    21h                ;  ...with system call
  324.     or    al,al                ; Did the write succeed?
  325.     jnz    dskful                ;  ...no, say disk is full
  326.     mov    word ptr orecn,cx        ; Point to next record
  327.     push    ds                ;  ...save a copy
  328.     mov    ax,ds                ; Get data segment
  329.     add    ax,800h                ;  ...go beyond roms
  330.     mov    ds,ax                ;  ...reload new segment
  331.     mov    ah,1Ah                ; Set disk transfer address
  332.     mov    dx,offset ibmbas        ;  ...where to set it to
  333.     int    21h                ; Set disk transfer address
  334.     pop    ds                ;  ...restore old segment
  335.     mov    ah,28h                ; Write unpatched BASICx.COM
  336.     mov    cx,word ptr ifsize        ;  ...input file (bytes)
  337.     mov    dx,offset ofile            ; Write more stuff out
  338.     int    21h                ;  ...with this call
  339.     or    al,al                ; Did the write succeed?
  340.     jnz    dskful                ;  ...no, say disk is full
  341.     mov    ah,10h                ; Worked, then close file
  342.     mov    dx,offset ofile            ; DX --> output FCB
  343.     int    21h                ; Issue the dos call
  344.     or    al,al                ;  ...did it close?
  345.     jnz    dskful                ; No, complain
  346.     ret                    ;  ...else back to caller
  347. ;
  348. tooful:    mov    dx,offset fulmsg        ; Fixup table overflowed
  349.     jmp    short    errxit            ;  ...on terminal
  350. ;
  351. toobig:    mov    dx,offset bigmsg        ;Complain, file is too big
  352.     jmp    short    errxit            ; ...jump to print message
  353. ;
  354. notcom:    mov    dx,offset commsg        ;Not a COM file, complain
  355.     jmp    short    errxit            ; ...jump to print message
  356. ;
  357. dskcre:    mov    dx,offset cremsg        ;Complain about open error
  358.     jmp    short    errxit            ;  ...jump to print message
  359. ;
  360. dskful:    mov    dx,offset dskmsg        ;Complain about disk full
  361. ;
  362. errxit:    mov    ah,09h                ; Function = print message
  363.     int    21h                ;  ...ask DOS to type it
  364.     int    20h                ; Then call the terminator
  365. wfile    endp                    ;  ...end write file procedure
  366. ;
  367. ; *** Start of real FCB structure for output file
  368. ;
  369. ofile    db    0                ; Disk number
  370.     db    'SBASIC'            ;  ...filename
  371. ofpat    db    ' '                ;  ...possibly 'A'
  372.     db    ' COM'                ;  ...extension
  373.     dw    0                ; Current record in FCB
  374. orecl    dw    0                ; Output record size
  375.     db    11h dup(0)            ;  ...rest of FCB
  376. orecn    dw    0,0                ; Output record number
  377. ;
  378. ; *** End of real FCB structure for output file
  379. ;
  380. bigmsg    db    cr,lf
  381.     db    'Your BASIC file is too big',cr,lf,7,'$'
  382. commsg    db    cr,lf
  383.     db    'Not COM file',cr,lf,7,'$'
  384. cremsg    db    cr,lf
  385.     db    'Can',27h,'t create SBASIC',cr,lf,7,'$'
  386. dskmsg    db    cr,lf
  387.     db    'Output disk full',cr,lf,7,'$'
  388. fulmsg    db    cr,lf
  389.     db    'Too many fixups',cr,lf,7,'$'
  390. ;
  391. subttl    hdr - everything beyond here added to SBASICx.COM image file
  392. ;
  393. extra    equ    27FFh                ; Minimum paragraphs to run
  394. ;
  395. hdr    label    byte                ; Header for SBASICs.COM
  396.     db    4Dh,5Ah                ;  ...image .EXE type
  397.     dw    ?                ; Fraction of block
  398.     dw    ?                ; Blocks in image
  399.     dw    0h                ; Number of relocations
  400.     dw    (0Fh+base-hdr)/10h        ; Header size in paragraphs
  401.     dw    (0Fh+fixups-ipl)/10h+extra    ; Minimum paragraphs to run
  402.     dw    0FFFFh                ; Maximum paragraphs to run
  403.     dw    0h                ; Offset for SS register
  404.     dw    tos-base            ;  ...value  SP register
  405.     dw    ?                ; Negative checksum
  406.     dw    0h                ; Offset for IP register
  407.     dw    0h                ;  ...value  CS register
  408.     dw    ?                ; Byte disp of reloc. list
  409.     dw    0                ;  ...not an overlay
  410. ;
  411.     dw    2 dup(?)            ; Align on paragraph boundary
  412. ;
  413. subttl  img - everything beyond here will apear in memory when image is loaded
  414. ;
  415. ; Everything below this line will appear in the output SBASICx.COM image, and
  416. ; will appear in memory when this image is loaded.  Memory offsets as follows
  417. ;
  418. ;    0000h  ==  Start of PSP  (Program Segment Prefix - not part of image )
  419. ;base:    0100h  ==  Symbol GO     (Setup COM environment in CS,DS and go there)
  420. ;    0111h  ==  Symbol MOVROM (check memory, copy basic ROM to high memory)
  421. ;    0139h  ==  Symbol RUNFIX (apply fixups to original BASICx.COM  image )
  422. ;    0152h  ==  Symbol MOVIPL (moves IPL code to stack area for execution )
  423. ;    0169h  ==  Symbol IPL    (moves ibm BASICx.COM to 0100h and starts it)
  424. ;    0192h  ==  Symbol FIXUPS (list of offsets into BASICx.COM for fixups )
  425. ;    0232h  ==  Symbol IBMBAS (copy  of ibm basic ROM set, without patches)
  426. ;    8232h  ==                (original ibm BASICx.COM without fixups done)
  427. ;end:    ????h  ==                (end BASICx.COM  May not exceed 96k in total)
  428. ;
  429. base    label    byte                ; At run-time appears at 0100h
  430. ;
  431. go    proc    far                ; Setup regs like COM file
  432.     cli                    ; No interrupts for now !!!
  433.     mov    ax,cs                ;  ...get code segment
  434.     sub    ax,10h                ;  ...then point to PSP
  435.     mov    ds,ax                ;  ...load into Data Segment
  436.     mov    ds:(100h+goseg-base),ax        ;  ...save copy for CS
  437.     db    0EAh                ; Jump far
  438. gooff    dw    100h+movrom-base        ;  ...offset  for IP
  439. goseg    dw    ?                ;  ...segment for CS
  440. go    endp
  441. ;
  442.     dw    ?                ; Bootstrap  word  for stack
  443. tos    label    word                ; Procedure GO becomes stack
  444. ;
  445. movrom    proc    near                ; Routine relocates ROM up hi
  446.     mov    si,offset ibmbas+100h-base    ; SI -> where 'ROM's live now
  447.     mov    di,0                ; DI -> where 'ROM's will  be
  448.     mov    ax,cs                ; Get our code segment
  449.     add    ax,extra-8FFh            ;   + minimum memory required
  450.     xor    al,al                ;  ...round down to even 4K
  451.     push    ax                ; Run-time segment for ROM set
  452.     mov    es,ax                ;  ...load into es for movsb
  453.     mov    cx,8000h            ; Bytes in basic 'ROM' set
  454.     cld                    ;  ...clear the direction
  455.     repz    movsb                ; Move ROMs from BASIC data area
  456.     mov    di,si                ; DI -> where BASICx.COM is now
  457.     xor    ax,ax                ; Prepare es segment to
  458.     mov    es,ax                ;  ...access vector area
  459.     mov    bx,60h                ; BX --> Basic vector into ROM
  460.     pop    dx                ; DX --> run-time 'ROM' segment
  461.     mov    es:[bx+2],dx            ;  ...save 'ROM' seg. in vector
  462.     mov    es:[bx+0],ax            ;  ...the  'ROM' offset is zero
  463. movrom    endp                    ; End of copy_rom procedure
  464. ;
  465. runfix    proc    near                ; Routine does runtime fixups
  466.     mov    cx,0000h            ; CX == number of fixups
  467. nfixes    =$ - 02h                ;  ...self-modifying code, ugh!
  468.     mov    si,offset fixups+100h-base    ; SI -> fixup table
  469.     mov    ax,ds                ; Get data segment
  470.     add    ax,800h                ;  ...go beyond ROMs
  471.     mov    es,ax                ;  ...and save it
  472.     sub    di,8000h            ; do this to avoid
  473. fixer:    lodsw                    ; AX == offset into BASICx.COM
  474.     mov    bx,ax                ;       copy offset into BX
  475.     mov    es:[bx+di],dx            ; Fixup ROM ref. in BASICx.COM
  476.     loop    fixer                ;  ..loop until all fixups done
  477. runfix    endp                    ; End of run-time fixup routine
  478. ;
  479. movipl    proc    far                ; Move IPL code to scratch area
  480.     mov    ax,cs                ; Get code segment
  481.     add    ax,offset extra-9FFh        ;  ...find scratch area
  482.     xor    al,al                ;  ...even boundary
  483.     push    ax                ; Save scratch segment
  484.     pop    es                ;  ...load into ES reg.
  485.     push    ax                ; Save scratch segment
  486.     mov    di,0h                ; DI -> where IPL code will run
  487.     push    di                ; Save offset to IPL code
  488.     mov    si,offset ipl+100h-base        ; SI -> where IPL code  is  now
  489.     mov    cx,offset fixups-ipl        ; CX == size of IPL code, bytes
  490.     repz    movsb                ;  ...copy IPL code to ipl area
  491.     ret                    ;  ...start final IPL sequence
  492. movipl    endp                    ; End of IPL relocate procedure
  493. ;
  494. ipl    proc    far                ; IPL code runs in  high memory
  495.     mov    cx,0000h            ; CX == size of BASICx.COM file
  496. ifsize    =$ - 02h                ;  ...self-modifying code, ugh!
  497.     mov    ax,ds                ; Save code segment copy
  498.     mov    es,ax                ;  ...load into extra seg
  499.     mov    word ptr cs:(iplseg-ipl),ax    ; Save code segment for ipl
  500.     add    ax,800h                ;  ...skip over 32K roms
  501.     mov    ds,ax                ; DS register --> ROM now 
  502.     mov    si,offset ibmbas+100h-base    ; SI -> area BASICx.COM is now
  503.     mov    di,100h                ; DI -> area BASICx.COM must go
  504.     repz    movsb                ; Copy BASICx.COM to low memory
  505.     mov    ax,es                ; Restore data segment
  506.     mov    ds,ax                ;  ...equal to extra seg
  507.     mov    ss,ax                ; Set stack seg for COM
  508.     mov    sp,0FFFEh            ;  ...stack reg for COM
  509.     sti                    ;  ...interrupts now safe
  510.     db    0EAh                ; JMP FAR segment:offset
  511. iploff    dw    100h                ;  ...offset for COM file
  512. iplseg    dw    ?                ;  ...Start  seg COM file
  513. ipl    endp                    ;  ..end of IPL procedure
  514. ;
  515. fixups    label    word                ; Fixups as offset in BASIC.COM
  516. ibmbas    equ    fixups + (2 * fixmax)        ; Contents of 'ROM's saved here
  517. prog    ends
  518. ;
  519. end    main
  520.